package com.xy.xyaicpzs.util;

import com.xy.xyaicpzs.domain.entity.DltDrawRecord;
import com.xy.xyaicpzs.domain.entity.DltFrontendHistoryAll;
import com.xy.xyaicpzs.domain.entity.DltFrontendHistory100;
import com.xy.xyaicpzs.domain.entity.DltFrontendHistoryTop;
import com.xy.xyaicpzs.domain.entity.DltFrontendHistoryTop100;
import com.xy.xyaicpzs.domain.entity.DltBackendHistoryAll;
import com.xy.xyaicpzs.domain.entity.DltBackendHistory100;
import com.xy.xyaicpzs.domain.entity.DltBackendHistoryTop;
import com.xy.xyaicpzs.domain.entity.DltBackendHistoryTop100;
import com.xy.xyaicpzs.domain.entity.D5;
import com.xy.xyaicpzs.domain.entity.D6;
import com.xy.xyaicpzs.domain.entity.D7;
import com.xy.xyaicpzs.domain.entity.D8;
import com.xy.xyaicpzs.domain.entity.D9;
import com.xy.xyaicpzs.domain.entity.D10;
import com.xy.xyaicpzs.domain.entity.D11;
import com.xy.xyaicpzs.domain.entity.D12;
import com.xy.xyaicpzs.mapper.DltDrawRecordMapper;
import com.xy.xyaicpzs.mapper.DltFrontendHistoryAllMapper;
import com.xy.xyaicpzs.mapper.DltFrontendHistory100Mapper;
import com.xy.xyaicpzs.mapper.DltFrontendHistoryTopMapper;
import com.xy.xyaicpzs.mapper.DltFrontendHistoryTop100Mapper;
import com.xy.xyaicpzs.mapper.DltBackendHistoryAllMapper;
import com.xy.xyaicpzs.mapper.DltBackendHistory100Mapper;
import com.xy.xyaicpzs.mapper.DltBackendHistoryTopMapper;
import com.xy.xyaicpzs.mapper.DltBackendHistoryTop100Mapper;
import com.xy.xyaicpzs.mapper.D5Mapper;
import com.xy.xyaicpzs.mapper.D6Mapper;
import com.xy.xyaicpzs.mapper.D7Mapper;
import com.xy.xyaicpzs.mapper.D8Mapper;
import com.xy.xyaicpzs.mapper.D9Mapper;
import com.xy.xyaicpzs.mapper.D10Mapper;
import com.xy.xyaicpzs.mapper.D11Mapper;
import com.xy.xyaicpzs.mapper.D12Mapper;
import com.xy.xyaicpzs.service.DltDrawRecordService;
import com.xy.xyaicpzs.service.DltFrontendHistoryAllService;
import com.xy.xyaicpzs.service.DltFrontendHistory100Service;
import com.xy.xyaicpzs.service.DltFrontendHistoryTopService;
import com.xy.xyaicpzs.service.DltFrontendHistoryTop100Service;
import com.xy.xyaicpzs.service.DltBackendHistoryAllService;
import com.xy.xyaicpzs.service.DltBackendHistory100Service;
import com.xy.xyaicpzs.service.DltBackendHistoryTopService;
import com.xy.xyaicpzs.service.DltBackendHistoryTop100Service;
import com.xy.xyaicpzs.service.D5Service;
import com.xy.xyaicpzs.service.D6Service;
import com.xy.xyaicpzs.service.D7Service;
import com.xy.xyaicpzs.service.D8Service;
import com.xy.xyaicpzs.service.D9Service;
import com.xy.xyaicpzs.service.D10Service;
import com.xy.xyaicpzs.service.D11Service;
import com.xy.xyaicpzs.service.D12Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 大乐透Excel数据导入工具类
 * 用于读取D1 sheet的数据并插入到dlt_draw_record表中
 */
@Slf4j
@Component
public class DltDataImporter {

    @Autowired
    private DltDrawRecordMapper dltDrawRecordMapper;

    @Autowired
    private DltDrawRecordService dltDrawRecordService;

    @Autowired
    private DltFrontendHistoryAllMapper dltFrontendHistoryAllMapper;

    @Autowired
    private DltFrontendHistory100Mapper dltFrontendHistory100Mapper;

    @Autowired
    private DltFrontendHistoryTopMapper dltFrontendHistoryTopMapper;

    @Autowired
    private DltFrontendHistoryTop100Mapper dltFrontendHistoryTop100Mapper;

    @Autowired
    private DltBackendHistoryAllMapper dltBackendHistoryAllMapper;

    @Autowired
    private DltBackendHistory100Mapper dltBackendHistory100Mapper;

    @Autowired
    private DltBackendHistoryTopMapper dltBackendHistoryTopMapper;

    @Autowired
    private DltBackendHistoryTop100Mapper dltBackendHistoryTop100Mapper;

    @Autowired
    private DltFrontendHistoryAllService dltFrontendHistoryAllService;

    @Autowired
    private DltFrontendHistory100Service dltFrontendHistory100Service;

    @Autowired
    private DltFrontendHistoryTopService dltFrontendHistoryTopService;

    @Autowired
    private DltFrontendHistoryTop100Service dltFrontendHistoryTop100Service;

    @Autowired
    private DltBackendHistoryAllService dltBackendHistoryAllService;

    @Autowired
    private DltBackendHistory100Service dltBackendHistory100Service;

    @Autowired
    private DltBackendHistoryTopService dltBackendHistoryTopService;

    @Autowired
    private DltBackendHistoryTop100Service dltBackendHistoryTop100Service;

    @Autowired
    private D5Mapper d5Mapper;

    @Autowired
    private D5Service d5Service;

    @Autowired
    private D6Mapper d6Mapper;

    @Autowired
    private D6Service d6Service;

    @Autowired
    private D7Mapper d7Mapper;

    @Autowired
    private D7Service d7Service;

    @Autowired
    private D8Mapper d8Mapper;

    @Autowired
    private D8Service d8Service;

    @Autowired
    private D9Mapper d9Mapper;

    @Autowired
    private D9Service d9Service;

    @Autowired
    private D10Mapper d10Mapper;

    @Autowired
    private D10Service d10Service;

    @Autowired
    private D11Mapper d11Mapper;

    @Autowired
    private D11Service d11Service;

    @Autowired
    private D12Mapper d12Mapper;

    @Autowired
    private D12Service d12Service;

    // ==================== D系列数据导入方法 ====================

    /**
     * 导入D5数据（D5工作表）
     */
    public void importD5Data(String filePath) {
        importGenericDData(filePath, "D5", d5Mapper, d5Service, D5.class);
    }

    /**
     * 导入D6数据（D6工作表）
     */
    public void importD6Data(String filePath) {
        importGenericDData(filePath, "D6", d6Mapper, d6Service, D6.class);
    }

    /**
     * 导入D7数据（D7工作表）
     */
    public void importD7Data(String filePath) {
        importGenericDData(filePath, "D7", d7Mapper, d7Service, D7.class);
    }

    /**
     * 导入D8数据（D8工作表）
     */
    public void importD8Data(String filePath) {
        importGenericDData(filePath, "D8", d8Mapper, d8Service, D8.class);
    }

    /**
     * 导入D9数据（D9工作表）
     */
    public void importD9Data(String filePath) {
        importGenericDData(filePath, "D9", d9Mapper, d9Service, D9.class);
    }

    /**
     * 导入D10数据（D10工作表）
     */
    public void importD10Data(String filePath) {
        importGenericDData(filePath, "D10", d10Mapper, d10Service, D10.class);
    }

    /**
     * 导入D11数据（D11工作表）
     */
    public void importD11Data(String filePath) {
        importGenericDData(filePath, "D11", d11Mapper, d11Service, D11.class);
    }

    /**
     * 导入D12数据（D12工作表）
     */
    public void importD12Data(String filePath) {
        importGenericDData(filePath, "D12", d12Mapper, d12Service, D12.class);
    }

    /**
     * 通用的D系列数据导入方法
     */
    private <T> void importGenericDData(String filePath, String sheetName, 
                                       com.baomidou.mybatisplus.core.mapper.BaseMapper<T> mapper,
                                       com.baomidou.mybatisplus.extension.service.IService<T> service,
                                       Class<T> entityClass) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            // 清空现有数据
            mapper.delete(null);
            log.info("清空现有{}数据...", sheetName);

            // 处理对应的sheet
            Sheet sheet = workbook.getSheet(sheetName);
            if (sheet != null) {
                log.info("开始导入{}数据", sheetName);
                
                // 读取数据并插入到对应表
                importGenericDSheetData(sheet, sheetName, service, entityClass);
                
                log.info("{}数据导入完成", sheetName);
            } else {
                log.warn("未找到{}工作表", sheetName);
            }

            log.info("{}数据导入完成", sheetName);

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    /**
     * 通用的D系列工作表数据导入方法
     */
    private <T> void importGenericDSheetData(Sheet sheet, String sheetName, 
                                            com.baomidou.mybatisplus.extension.service.IService<T> service,
                                            Class<T> entityClass) {
        log.info("开始导入{}数据（系数数据）...", sheetName);
        List<T> dataList = new ArrayList<>();

        // 获取数据行数，跳过标题行
        int lastRowNum = sheet.getLastRowNum();
        
        // 计算组数，每组占用3列，从A列开始
        int totalCols = 0;
        if (lastRowNum > 0) {
            Row firstDataRow = sheet.getRow(1);
            if (firstDataRow != null) {
                totalCols = firstDataRow.getLastCellNum();
            }
        }
        
        int groupCount = totalCols / 3 + 1; // 每组3列
        log.info("检测到{}组数据，共{}列，数据行数{}行", groupCount, totalCols, lastRowNum);
        
        // 调试：打印前几行的原始数据
        log.info("=== 调试信息：前5行原始数据 ===");
        for (int debugRow = 0; debugRow <= Math.min(5, lastRowNum); debugRow++) {
            Row row = sheet.getRow(debugRow);
            if (row != null) {
                StringBuilder rowData = new StringBuilder();
                rowData.append("行").append(debugRow + 1).append(": ");
                for (int col = 0; col < Math.min(totalCols, 20); col++) {
                    Cell cell = row.getCell(col);
                    String cellValue = "null";
                    if (cell != null) {
                        try {
                            switch (cell.getCellType()) {
                                case STRING:
                                    cellValue = "\"" + cell.getStringCellValue() + "\"";
                                    break;
                                case NUMERIC:
                                    cellValue = String.valueOf(cell.getNumericCellValue());
                                    break;
                                default:
                                    cellValue = cell.toString();
                            }
                        } catch (Exception e) {
                            cellValue = "error";
                        }
                    }
                    rowData.append("[").append((char)('A' + col)).append(":").append(cellValue).append("] ");
                }
                log.info(rowData.toString());
            }
        }
        log.info("=== 调试信息结束 ===");

        // 遍历每组数据
        for (int group = 0; group < groupCount; group++) {
            int masterBallNumber = group + 1; // 主球号从1开始
            int slaveBallCol = group * 3 + 1; // 从球号列：0,3,6...（A,D,G列）
            int coefficientCol = group * 3 + 2; // 系数列：1,4,7...（B,E,H列）
            
            log.info("处理第{}组数据（主球{}号），从球号列：{}，系数列：{}", group + 1, masterBallNumber, slaveBallCol, coefficientCol);

            int validDataCount = 0; // 统计这组有效数据数量
            int emptyBallNumber = 0; // 统计球号为空的数量
            int emptyCoefficient = 0; // 统计系数为空的数量

            // 遍历所有数据行（跳过标题行）
            for (int rowIndex = 1; rowIndex <= lastRowNum; rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                if (row == null) {
                    continue;
                }

                // 从Excel中读取从球号
                Integer slaveBallNumber = getCellIntegerValue(row.getCell(slaveBallCol));
                if (slaveBallNumber == null) {
                    emptyBallNumber++;
                    continue; // 如果球号为空，跳过这行
                }

                // 系数（从对应组的系数列读取）
                Double coefficient = getCellNumericValue(row.getCell(coefficientCol));

                if (coefficient != null) {
                    try {
                        T entity = entityClass.getDeclaredConstructor().newInstance();
                        
                        // 使用反射设置字段值
                        entityClass.getMethod("setMasterBallNumber", Integer.class).invoke(entity, masterBallNumber);
                        entityClass.getMethod("setSlaveBallNumber", Integer.class).invoke(entity, slaveBallNumber);
                        entityClass.getMethod("setCoefficient", Double.class).invoke(entity, roundToTwoDecimalPlaces(coefficient));
                        
                        dataList.add(entity);
                        validDataCount++;
                        
                        log.info("添加{}数据：主球{}，从球{}，Excel行{}，系数{}", 
                            sheetName, masterBallNumber, slaveBallNumber, rowIndex + 1, coefficient);
                    } catch (Exception e) {
                        log.error("创建{}实体失败：{}", sheetName, e.getMessage(), e);
                    }
                } else {
                    emptyCoefficient++;
                    log.debug("第{}组第{}行系数为空，球号{}，跳过", group + 1, rowIndex + 1, slaveBallNumber);
                }
            }
            
            // 统计这组的处理结果
            log.info("第{}组统计：有效数据{}条，球号为空{}条，系数为空{}条", 
                group + 1, validDataCount, emptyBallNumber, emptyCoefficient);
        }

        // 批量插入前的调试信息
        log.info("=== 准备批量插入{}数据 ===", sheetName);
        log.info("待插入数据总数：{}", dataList.size());
        if (!dataList.isEmpty()) {
            // 打印前几条数据作为样例
            for (int i = 0; i < Math.min(5, dataList.size()); i++) {
                T entity = dataList.get(i);
                try {
                    Integer masterBall = (Integer) entityClass.getMethod("getMasterBallNumber").invoke(entity);
                    Integer slaveBall = (Integer) entityClass.getMethod("getSlaveBallNumber").invoke(entity);
                    Double coeff = (Double) entityClass.getMethod("getCoefficient").invoke(entity);
                    log.info("样例数据{}：主球{}，从球{}，系数{}", i + 1, masterBall, slaveBall, coeff);
                } catch (Exception e) {
                    log.warn("获取样例数据失败：{}", e.getMessage());
                }
            }
        }
        log.info("=== 调试信息结束 ===");

        // 批量插入
        if (!dataList.isEmpty()) {
            try {
                boolean result = service.saveBatch(dataList);
                log.info("批量插入结果：{}，成功导入{}条{}数据（系数数据）", result, dataList.size(), sheetName);
            } catch (Exception e) {
                log.error("批量插入{}数据失败：{}", sheetName, e.getMessage(), e);
                throw e;
            }
            
            // 验证数据统计
            log.info("{}数据导入统计：", sheetName);
            for (int master = 1; master <= Math.min(groupCount, 12); master++) {
                final int masterNum = master;
                long count = dataList.stream().filter(entity -> {
                    try {
                        Integer masterBall = (Integer) entityClass.getMethod("getMasterBallNumber").invoke(entity);
                        return masterBall != null && masterBall.equals(masterNum);
                    } catch (Exception e) {
                        return false;
                    }
                }).count();
                log.info("主球{}号记录数：{}", masterNum, count);
            }
        } else {
            log.warn("未找到有效的{}数据", sheetName);
        }
    }

    // ==================== 其他导入方法 ====================

    /**
     * 完整导入大乐透数据（D3-D12工作表）
     * 包含前区历史数据、后区历史数据和系数数据
     */
    public void importDltCompleteData(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            StringBuilder importResults = new StringBuilder();
            StringBuilder errorMessages = new StringBuilder();
            
            // 导入D3数据（前区历史数据）
            try {
                importDltFrontendHistoryData(filePath);
                importResults.append("D3(前区历史数据)导入成功; ");
            } catch (Exception e) {
                log.warn("D3数据导入失败：{}", e.getMessage());
                errorMessages.append("D3导入失败: ").append(e.getMessage()).append("; ");
            }
            
            // 导入D4数据（后区历史数据）
            try {
                importDltBackendHistoryData(filePath);
                importResults.append("D4(后区历史数据)导入成功; ");
            } catch (Exception e) {
                log.warn("D4数据导入失败：{}", e.getMessage());
                errorMessages.append("D4导入失败: ").append(e.getMessage()).append("; ");
            }
            
            // 导入D5-D12数据（系数数据）
            for (int tableNum = 5; tableNum <= 12; tableNum++) {
                try {
                    switch (tableNum) {
                        case 5:
                            importD5Data(filePath);
                            break;
                        case 6:
                            importD6Data(filePath);
                            break;
                        case 7:
                            importD7Data(filePath);
                            break;
                        case 8:
                            importD8Data(filePath);
                            break;
                        case 9:
                            importD9Data(filePath);
                            break;
                        case 10:
                            importD10Data(filePath);
                            break;
                        case 11:
                            importD11Data(filePath);
                            break;
                        case 12:
                            importD12Data(filePath);
                            break;
                    }
                    importResults.append("D").append(tableNum).append("导入成功; ");
                } catch (Exception e) {
                    log.warn("D{}数据导入失败：{}", tableNum, e.getMessage());
                    errorMessages.append("D").append(tableNum).append("导入失败: ").append(e.getMessage()).append("; ");
                }
            }
            
            // 记录导入结果
            if (errorMessages.length() > 0) {
                log.warn("完整数据导入部分失败: {} 错误信息: {}", importResults.toString(), errorMessages.toString());
                throw new RuntimeException("部分导入失败: " + importResults.toString() + " 错误信息: " + errorMessages.toString());
            } else {
                log.info("完整数据导入全部成功: {}", importResults.toString());
            }

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    /**
     * 导入大乐透前区历史数据（D3工作表）
     */
    public void importDltFrontendHistoryData(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            // 清空现有前区历史数据
            clearFrontendHistoryData();

            // 处理D3 sheet（前区历史数据）
            Sheet d3Sheet = workbook.getSheet("D3");
            if (d3Sheet != null) {
                int lastRowNum = d3Sheet.getLastRowNum();
                log.info("开始导入D3数据（前区历史数据），共{}行", lastRowNum);

                // 读取数据并插入到四个表
                importDltFrontendHistoryAllData(d3Sheet, lastRowNum);
                importDltFrontendHistory100Data(d3Sheet, lastRowNum);
                importDltFrontendHistoryTopData(d3Sheet, lastRowNum);
                importDltFrontendHistoryTop100Data(d3Sheet, lastRowNum);

                log.info("D3数据（前区历史数据）导入完成");
            } else {
                log.warn("未找到D3工作表");
            }

            log.info("大乐透前区历史数据导入完成");

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    /**
     * 导入大乐透后区历史数据（D4工作表）
     */
    public void importDltBackendHistoryData(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            // 清空现有后区历史数据
            clearBackendHistoryData();

            // 处理D4 sheet（后区历史数据）
            Sheet d4Sheet = workbook.getSheet("D4");
            if (d4Sheet != null) {
                int lastRowNum = d4Sheet.getLastRowNum();
                log.info("开始导入D4数据（后区历史数据），共{}行", lastRowNum);

                // 读取数据并插入到四个表
                importDltBackendHistoryAllData(d4Sheet, lastRowNum);
                importDltBackendHistory100Data(d4Sheet, lastRowNum);
                importDltBackendHistoryTopData(d4Sheet, lastRowNum);
                importDltBackendHistoryTop100Data(d4Sheet, lastRowNum);

                log.info("D4数据（后区历史数据）导入完成");
            } else {
                log.warn("未找到D4工作表");
            }

            log.info("大乐透后区历史数据导入完成");

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    /**
     * 导入大乐透Excel数据到数据库
     */
    public void importDltDrawData(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            // 清空现有数据
            clearExistingData();

            // 处理D1 sheet（大乐透开奖数据）
            Sheet d1Sheet = workbook.getSheet("D1");
            if (d1Sheet != null) {
                log.info("开始导入D1数据（大乐透开奖信息）");
                
                // 读取D1数据并插入到dlt_draw_record表
                importD1Data(d1Sheet);
                
                log.info("D1数据（大乐透开奖信息）导入完成");
            } else {
                log.warn("未找到D1工作表");
            }

            log.info("大乐透数据导入完成");

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    /**
     * 追加导入大乐透Excel数据到数据库（不清空现有数据）
     */
    public void appendDltDrawData(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
            
            // 处理D1 sheet（大乐透开奖数据）
            Sheet d1Sheet = workbook.getSheet("D1");
            if (d1Sheet != null) {
                log.info("开始追加导入D1数据（大乐透开奖信息）");
                
                // 读取D1数据并追加到dlt_draw_record表
                appendD1Data(d1Sheet);
                
                log.info("D1数据（大乐透开奖信息）追加导入完成");
            } else {
                log.warn("未找到D1工作表");
            }

            log.info("大乐透追加数据导入完成");

        } catch (IOException e) {
            log.error("读取Excel文件失败：{}", e.getMessage(), e);
            throw new RuntimeException("Excel文件读取失败", e);
        }
    }

    // ==================== 清空数据方法 ====================

    /**
     * 清空现有大乐透前区历史数据
     */
    private void clearFrontendHistoryData() {
        log.info("清空现有大乐透前区历史数据...");
        // 使用MyBatis-Plus的delete方法清空表
        dltFrontendHistoryAllMapper.delete(null);
        dltFrontendHistory100Mapper.delete(null);
        dltFrontendHistoryTopMapper.delete(null);
        dltFrontendHistoryTop100Mapper.delete(null);
    }

    /**
     * 清空现有大乐透后区历史数据
     */
    private void clearBackendHistoryData() {
        log.info("清空现有大乐透后区历史数据...");
        // 使用MyBatis-Plus的delete方法清空表
        dltBackendHistoryAllMapper.delete(null);
        dltBackendHistory100Mapper.delete(null);
        dltBackendHistoryTopMapper.delete(null);
        dltBackendHistoryTop100Mapper.delete(null);
    }

    /**
     * 清空现有大乐透数据
     */
    private void clearExistingData() {
        log.info("清空现有大乐透数据...");
        // 使用MyBatis-Plus的delete方法清空表
        dltDrawRecordMapper.delete(null);
    }

    // ==================== 具体导入方法 ====================

    /**
     * 导入D1数据（大乐透开奖信息）
     * 数据结构：标准表格结构
     * A列：开奖期号，B列：开奖日期
     * C-G列：前区1-5，H-I列：后区1-2
     */
    private void importD1Data(Sheet sheet) {
        log.info("开始导入D1数据（大乐透开奖信息）...");
        List<DltDrawRecord> dataList = new ArrayList<>();

        // 获取数据行数，跳过标题行
        int lastRowNum = sheet.getLastRowNum();
        log.info("D1工作表共{}行数据（包含标题行）", lastRowNum + 1);

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltDrawRecord entity = new DltDrawRecord();
            
            // A列: 开奖期号
            String drawId = getCellStringValue(row.getCell(0));
            if (drawId == null || drawId.trim().isEmpty()) {
                log.warn("第{}行开奖期号为空，跳过", i + 1);
                continue;
            }
            entity.setDrawId(drawId.trim());
            
            // B列: 开奖日期
            Date drawDate = getCellDateValue(row.getCell(1));
            if (drawDate == null) {
                log.warn("第{}行开奖日期为空，跳过", i + 1);
                continue;
            }
            entity.setDrawDate(drawDate);
            
            // C列: 前区1
            entity.setFrontBall1(getCellIntegerValue(row.getCell(2)));
            
            // D列: 前区2
            entity.setFrontBall2(getCellIntegerValue(row.getCell(3)));
            
            // E列: 前区3
            entity.setFrontBall3(getCellIntegerValue(row.getCell(4)));
            
            // F列: 前区4
            entity.setFrontBall4(getCellIntegerValue(row.getCell(5)));
            
            // G列: 前区5
            entity.setFrontBall5(getCellIntegerValue(row.getCell(6)));
            
            // H列: 后区1
            entity.setBackBall1(getCellIntegerValue(row.getCell(7)));
            
            // I列: 后区2
            entity.setBackBall2(getCellIntegerValue(row.getCell(8)));

            // 验证必要字段
            if (entity.getFrontBall1() != null && entity.getFrontBall2() != null && 
                entity.getFrontBall3() != null && entity.getFrontBall4() != null && 
                entity.getFrontBall5() != null && entity.getBackBall1() != null && 
                entity.getBackBall2() != null) {
                dataList.add(entity);
                log.debug("添加大乐透开奖记录：期号{}，日期{}，前区{}-{}-{}-{}-{}，后区{}-{}", 
                    entity.getDrawId(), entity.getDrawDate(),
                    entity.getFrontBall1(), entity.getFrontBall2(), entity.getFrontBall3(),
                    entity.getFrontBall4(), entity.getFrontBall5(),
                    entity.getBackBall1(), entity.getBackBall2());
            } else {
                log.warn("第{}行数据不完整，跳过", i + 1);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltDrawRecordService.saveBatch(dataList);
            log.info("成功导入{}条D1数据（大乐透开奖信息）", dataList.size());
        } else {
            log.warn("未找到有效的D1数据");
        }
    }

    /**
     * 追加导入D1数据（大乐透开奖信息），检查重复数据
     */
    private void appendD1Data(Sheet sheet) {
        log.info("开始追加导入D1数据（大乐透开奖信息）...");
        List<DltDrawRecord> dataList = new ArrayList<>();
        int duplicateCount = 0;
        int newCount = 0;

        // 获取数据行数，跳过标题行
        int lastRowNum = sheet.getLastRowNum();
        log.info("D1工作表共{}行数据（包含标题行）", lastRowNum + 1);

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltDrawRecord entity = new DltDrawRecord();
            
            // A列: 开奖期号
            String drawId = getCellStringValue(row.getCell(0));
            if (drawId == null || drawId.trim().isEmpty()) {
                log.warn("第{}行开奖期号为空，跳过", i + 1);
                continue;
            }
            entity.setDrawId(drawId.trim());
            
            // 检查该期号是否已存在
            DltDrawRecord existingRecord = dltDrawRecordService.lambdaQuery()
                    .eq(DltDrawRecord::getDrawId, drawId.trim())
                    .one();
            if (existingRecord != null) {
                duplicateCount++;
                log.debug("大乐透开奖期号{}已存在，跳过", drawId.trim());
                continue;
            }
            
            // B列: 开奖日期
            Date drawDate = getCellDateValue(row.getCell(1));
            if (drawDate == null) {
                log.warn("第{}行开奖日期为空，跳过", i + 1);
                continue;
            }
            entity.setDrawDate(drawDate);
            
            // C列: 前区1
            entity.setFrontBall1(getCellIntegerValue(row.getCell(2)));
            
            // D列: 前区2
            entity.setFrontBall2(getCellIntegerValue(row.getCell(3)));
            
            // E列: 前区3
            entity.setFrontBall3(getCellIntegerValue(row.getCell(4)));
            
            // F列: 前区4
            entity.setFrontBall4(getCellIntegerValue(row.getCell(5)));
            
            // G列: 前区5
            entity.setFrontBall5(getCellIntegerValue(row.getCell(6)));
            
            // H列: 后区1
            entity.setBackBall1(getCellIntegerValue(row.getCell(7)));
            
            // I列: 后区2
            entity.setBackBall2(getCellIntegerValue(row.getCell(8)));

            // 验证必要字段
            if (entity.getFrontBall1() != null && entity.getFrontBall2() != null && 
                entity.getFrontBall3() != null && entity.getFrontBall4() != null && 
                entity.getFrontBall5() != null && entity.getBackBall1() != null && 
                entity.getBackBall2() != null) {
                dataList.add(entity);
                newCount++;
                log.debug("添加新大乐透开奖记录：期号{}，日期{}，前区{}-{}-{}-{}-{}，后区{}-{}", 
                    entity.getDrawId(), entity.getDrawDate(),
                    entity.getFrontBall1(), entity.getFrontBall2(), entity.getFrontBall3(),
                    entity.getFrontBall4(), entity.getFrontBall5(),
                    entity.getBackBall1(), entity.getBackBall2());
            } else {
                log.warn("第{}行数据不完整，跳过", i + 1);
            }
        }

        // 批量插入新数据
        if (!dataList.isEmpty()) {
            dltDrawRecordService.saveBatch(dataList);
            log.info("成功追加导入{}条新的D1数据（大乐透开奖信息）", dataList.size());
        } else {
            log.info("没有新的D1数据需要导入");
        }
        
        log.info("追加导入统计：新增{}条，跳过重复{}条", newCount, duplicateCount);
    }

    // ==================== 工具方法 ====================

    /**
     * 获取单元格的字符串值
     */
    private String getCellStringValue(Cell cell) {
        if (cell == null) return null;
        
        try {
            switch (cell.getCellType()) {
                case STRING:
                    return cell.getStringCellValue();
                case NUMERIC:
                    // 如果是数字，转换为字符串
                    double numValue = cell.getNumericCellValue();
                    // 如果是整数，不显示小数点
                    if (numValue == (long) numValue) {
                        return String.valueOf((long) numValue);
                    } else {
                        return String.valueOf(numValue);
                    }
                case FORMULA:
                    try {
                        return cell.getStringCellValue();
                    } catch (Exception e) {
                        // 如果公式结果是数字，转换为字符串
                        double formulaNumValue = cell.getNumericCellValue();
                        if (formulaNumValue == (long) formulaNumValue) {
                            return String.valueOf((long) formulaNumValue);
                        } else {
                            return String.valueOf(formulaNumValue);
                        }
                    }
                case BLANK:
                    return null;
                default:
                    log.warn("不支持的单元格类型：{}", cell.getCellType());
                    return null;
            }
        } catch (Exception e) {
            log.warn("读取单元格字符串值失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 获取单元格的数值（保留两位小数）
     */
    private Double getCellNumericValue(Cell cell) {
        if (cell == null) return null;
        
        try {
            double value = 0.0;
            switch (cell.getCellType()) {
                case NUMERIC:
                    value = cell.getNumericCellValue();
                    break;
                case STRING:
                    String strValue = cell.getStringCellValue().trim();
                    if (strValue.isEmpty()) {
                        return null;
                    }
                    try {
                        value = Double.parseDouble(strValue);
                    } catch (NumberFormatException e) {
                        log.warn("无法解析单元格数值：{}", strValue);
                        return null;
                    }
                    break;
                case FORMULA:
                    try {
                        value = cell.getNumericCellValue();
                    } catch (Exception e) {
                        log.warn("无法获取公式单元格的数值：{}", e.getMessage());
                        return null;
                    }
                    break;
                case BLANK:
                    return null;
                default:
                    log.warn("不支持的单元格类型：{}", cell.getCellType());
                    return null;
            }
            
            // 保留两位小数
            return roundToTwoDecimalPlaces(value);
            
        } catch (Exception e) {
            log.warn("读取单元格数据失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 获取单元格的整数值
     */
    private Integer getCellIntegerValue(Cell cell) {
        Double numericValue = getCellNumericValue(cell);
        return numericValue != null ? numericValue.intValue() : null;
    }

    /**
     * 获取单元格的Date值
     */
    private Date getCellDateValue(Cell cell) {
        if (cell == null) return null;
        
        try {
            switch (cell.getCellType()) {
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return cell.getDateCellValue();
                    } else {
                        // 如果是数字，尝试转换为日期
                        return DateUtil.getJavaDate(cell.getNumericCellValue());
                    }
                case STRING:
                    String strValue = cell.getStringCellValue().trim();
                    if (strValue.isEmpty()) return null;
                    // 尝试解析字符串日期，支持多种格式
                    return parseStringToDate(strValue);
                case FORMULA:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return cell.getDateCellValue();
                    } else {
                        return DateUtil.getJavaDate(cell.getNumericCellValue());
                    }
                case BLANK:
                    return null;
                default:
                    log.warn("不支持的日期单元格类型：{}", cell.getCellType());
                    return null;
            }
        } catch (Exception e) {
            log.warn("读取Date值失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 解析字符串为日期
     */
    private Date parseStringToDate(String dateStr) {
        try {
            // 支持多种日期格式
            SimpleDateFormat[] formats = {
                new SimpleDateFormat("yyyy-MM-dd"),
                new SimpleDateFormat("yyyy/MM/dd"),
                new SimpleDateFormat("yyyy-M-d"),
                new SimpleDateFormat("yyyy/M/d"),
                new SimpleDateFormat("yyyy年MM月dd日"),
                new SimpleDateFormat("yyyy年M月d日")
            };
            
            for (SimpleDateFormat format : formats) {
                try {
                    return format.parse(dateStr);
                } catch (java.text.ParseException ignored) {
                    // 继续尝试下一种格式
                }
            }
            
            log.warn("无法解析日期字符串：{}", dateStr);
            return null;
        } catch (Exception e) {
            log.warn("解析日期字符串失败：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 将数值保留两位小数
     * @param value 原始数值
     * @return 保留两位小数的数值
     */
    private Double roundToTwoDecimalPlaces(double value) {
        if (Double.isNaN(value) || Double.isInfinite(value)) {
            return null;
        }
        
        try {
            BigDecimal bd = new BigDecimal(Double.toString(value));
            return bd.setScale(2, RoundingMode.HALF_UP).doubleValue();
        } catch (Exception e) {
            log.warn("数值格式化失败：{}", value);
            return value;
        }
    }

    // ==================== D3/D4数据导入方法 ====================

    /**
     * 导入大乐透前区全部历史数据 (列A-G)
     */
    private void importDltFrontendHistoryAllData(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透前区全部历史数据...");
        List<DltFrontendHistoryAll> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltFrontendHistoryAll entity = new DltFrontendHistoryAll();
            
            // 列A: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(0)));
            
            // 列B: 出现频次
            entity.setFrequencyCount(getCellIntegerValue(row.getCell(1)));
            
            // 列C: 出现频率百分比
            entity.setFrequencyPercentage(getCellNumericValue(row.getCell(2)));
            
            // 列D: 平均隐现期
            entity.setAverageHiddenAppear(getCellIntegerValue(row.getCell(3)));
            
            // 列E: 最长隐现期
            entity.setMaxHiddenInterval(getCellIntegerValue(row.getCell(4)));
            
            // 列F: 最多连出期
            entity.setMaxConsecutive(getCellIntegerValue(row.getCell(5)));
            
            // 列G: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(6)));

            if (entity.getBallNumber() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltFrontendHistoryAllService.saveBatch(dataList);
            log.info("成功导入{}条大乐透前区全部历史数据", dataList.size());
        }
    }

    /**
     * 导入大乐透前区最近100期数据 (列H-M)
     */
    private void importDltFrontendHistory100Data(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透前区最近100期数据...");
        List<DltFrontendHistory100> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltFrontendHistory100 entity = new DltFrontendHistory100();
            
            // 使用第一列的球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(0)));
            
            // 列H: 出现频次
            entity.setFrequencyCount(getCellIntegerValue(row.getCell(8)));
            
            // 列I: 平均隐现期
            entity.setAverageHiddenAppear(getCellNumericValue(row.getCell(9)));
            
            // 列J: 当前隐现期
            entity.setCurrentHiddenInterval(getCellIntegerValue(row.getCell(10)));
            
            // 列K: 最多连出期
            entity.setMaxConsecutive(getCellIntegerValue(row.getCell(11)));
            
            // 列L: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(12)));

            if (entity.getBallNumber() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltFrontendHistory100Service.saveBatch(dataList);
            log.info("成功导入{}条大乐透前区最近100期数据", dataList.size());
        }
    }

    /**
     * 导入大乐透前区历史数据排行 (列M-O)
     */
    private void importDltFrontendHistoryTopData(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透前区历史数据排行...");
        List<DltFrontendHistoryTop> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltFrontendHistoryTop entity = new DltFrontendHistoryTop();
            
            // 列M: 排位
            entity.setRanking(getCellIntegerValue(row.getCell(14)));
            
            // 列N: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(15)));
            
            // 列O: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(16)));

            if (entity.getBallNumber() != null && entity.getRanking() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltFrontendHistoryTopService.saveBatch(dataList);
            log.info("成功导入{}条大乐透前区历史数据排行", dataList.size());
        }
    }

    /**
     * 导入大乐透前区百期数据排行 (列P-R)
     */
    private void importDltFrontendHistoryTop100Data(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透前区百期数据排行...");
        List<DltFrontendHistoryTop100> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltFrontendHistoryTop100 entity = new DltFrontendHistoryTop100();
            
            // 列P: 排位
            entity.setRanking(getCellIntegerValue(row.getCell(18)));
            
            // 列Q: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(19)));
            
            // 列R: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(20)));

            if (entity.getBallNumber() != null && entity.getRanking() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltFrontendHistoryTop100Service.saveBatch(dataList);
            log.info("成功导入{}条大乐透前区百期数据排行", dataList.size());
        }
    }

    /**
     * 导入大乐透后区全部历史数据 (列A-G)
     */
    private void importDltBackendHistoryAllData(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透后区全部历史数据...");
        List<DltBackendHistoryAll> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltBackendHistoryAll entity = new DltBackendHistoryAll();
            
            // 列A: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(0)));
            
            // 列B: 出现频次
            entity.setFrequencyCount(getCellIntegerValue(row.getCell(1)));
            
            // 列C: 出现频率百分比
            entity.setFrequencyPercentage(getCellNumericValue(row.getCell(2)));
            
            // 列D: 平均隐现期
            entity.setAverageHiddenAppear(getCellIntegerValue(row.getCell(3)));
            
            // 列E: 最长隐现期
            entity.setMaxHiddenInterval(getCellIntegerValue(row.getCell(4)));
            
            // 列F: 最多连出期
            entity.setMaxConsecutive(getCellIntegerValue(row.getCell(5)));
            
            // 列G: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(6)));

            if (entity.getBallNumber() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltBackendHistoryAllService.saveBatch(dataList);
            log.info("成功导入{}条大乐透后区全部历史数据", dataList.size());
        }
    }

    /**
     * 导入大乐透后区最近100期数据 (列H-L)
     */
    private void importDltBackendHistory100Data(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透后区最近100期数据...");
        List<DltBackendHistory100> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltBackendHistory100 entity = new DltBackendHistory100();
            
            // 使用第一列的球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(0)));
            
            // 列H: 出现频次
            entity.setFrequencyCount(getCellIntegerValue(row.getCell(8)));
            
            // 列I: 平均隐现期
            entity.setAverageHiddenAppear(getCellNumericValue(row.getCell(9)));
            
            // 列J: 当前隐现期
            entity.setCurrentHiddenInterval(getCellIntegerValue(row.getCell(10)));
            
            // 列K: 最多连出期
            entity.setMaxConsecutive(getCellIntegerValue(row.getCell(11)));
            
            // 列L: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(12)));

            if (entity.getBallNumber() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltBackendHistory100Service.saveBatch(dataList);
            log.info("成功导入{}条大乐透后区最近100期数据", dataList.size());
        }
    }

    /**
     * 导入大乐透后区历史数据排行 (列M-O)
     */
    private void importDltBackendHistoryTopData(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透后区历史数据排行...");
        List<DltBackendHistoryTop> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltBackendHistoryTop entity = new DltBackendHistoryTop();
            
            // 列M: 排位
            entity.setRanking(getCellIntegerValue(row.getCell(14)));
            
            // 列N: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(15)));
            
            // 列O: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(16)));

            if (entity.getBallNumber() != null && entity.getRanking() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltBackendHistoryTopService.saveBatch(dataList);
            log.info("成功导入{}条大乐透后区历史数据排行", dataList.size());
        }
    }

    /**
     * 导入大乐透后区百期数据排行 (列P-R)
     */
    private void importDltBackendHistoryTop100Data(Sheet sheet, int lastRowNum) {
        log.info("开始导入大乐透后区百期数据排行...");
        List<DltBackendHistoryTop100> dataList = new ArrayList<>();

        for (int i = 1; i <= lastRowNum; i++) { // 跳过标题行
            Row row = sheet.getRow(i);
            if (row == null) continue;

            DltBackendHistoryTop100 entity = new DltBackendHistoryTop100();
            
            // 列P: 排位
            entity.setRanking(getCellIntegerValue(row.getCell(18)));
            
            // 列Q: 球号
            entity.setBallNumber(getCellIntegerValue(row.getCell(19)));
            
            // 列R: 活跃系数
            entity.setActiveCoefficient(getCellNumericValue(row.getCell(20)));

            if (entity.getBallNumber() != null && entity.getRanking() != null) {
                dataList.add(entity);
            }
        }

        // 批量插入
        if (!dataList.isEmpty()) {
            dltBackendHistoryTop100Service.saveBatch(dataList);
            log.info("成功导入{}条大乐透后区百期数据排行", dataList.size());
        }
    }
}